package benchmarks.tpch.mongo.queries;

import api.Configuration;
import api.connection.ConnectionMongo;
import api.connection.DBConnection;
import api.result.Result;
import com.mongodb.*;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.Date;

public class Q15Mongo extends GenericQueryMongo {
    public static final String queryName = "Q15";

    public Q15Mongo(){
        super.queryName = queryName;
    }

    private static String matchStringQuery = "{ $match : " +
            "{\"shipdate\" : { \"$gte\" : new Date(1996, 0, 1), \"$lt\" : new Date(1996, 3, 1) } } " +
            "}";

    private static String projectStringQuery = "{ $project : { " +
            "\"_id\" : 0, " +
            "\"revenue\" : {$multiply : [\"$extendedprice\", {$subtract : [1, \"$discount\"] }] }, \"supplier_no\" : \"$partsupp.supplier.suppkey\", " +
            "\"name\" : \"$partsupp.supplier.name\", " +
            "\"address\" : \"$partsupp.supplier.address\", " +
            "\"phone\" : \"$partsupp.supplier.phone\" }}";

    private static String groupStringQuery = "{ $group : { " +
            "_id : \"$supplier_no\", " +
            "total_revenue : { $sum : \"$revenue\" }, name : {$first : \"$name\"}, " +
            "address : {$first : \"$address\"}, " +
            "phone : {$first : \"$phone\"} }}";

    private static String sortStringQuery = "{ $sort : {\"_id\" : 1}}";

    public Result run(DBConnection dbConnection) {
        ConnectionMongo connectionMongo = (ConnectionMongo)dbConnection;
        MongoClient mongoClient = connectionMongo.makeConnection();
        MongoDatabase database = mongoClient.getDatabase("tpch");
        BsonDocument matchBsonQuery = BsonDocument.parse(matchStringQuery);
        BsonDocument projectBsonQuery = BsonDocument.parse(projectStringQuery);
        BsonDocument groupBsonQuery = BsonDocument.parse(groupStringQuery);
        BsonDocument sortBsonQuery = BsonDocument.parse(sortStringQuery);
        ArrayList<Bson> aggregateQuery = new ArrayList<>();
        aggregateQuery.add(matchBsonQuery);
        aggregateQuery.add(projectBsonQuery);
        aggregateQuery.add(groupBsonQuery);
        aggregateQuery.add(sortBsonQuery);
        AggregateIterable<Document> result  = database.getCollection("deals").aggregate(aggregateQuery);
        MongoCursor<Document> iterator = result.iterator();
        ArrayList<Document> results = new ArrayList<>();
        while (iterator.hasNext()) {
            results.add(iterator.next());
        }
//        System.out.println("Q1 ok");
        return null;
    }

//    public Result run(DBConnection dbConnection){
//        MongoClient mongoClient = (MongoClient)dbConnection.makeConnection();
//        DB db = mongoClient.getDB("tpch");
//        DBCollection collection = db.getCollection("deals");
//
//        Date startDate = new Date(96, 0, 1);
//
//        BasicDBObject match = new BasicDBObject();
//        BasicDBObject dateRange = new BasicDBObject();
//        dateRange.append("$gte", startDate).append("$lt", new Date(startDate.getYear(), startDate.getMonth() + 3, startDate.getDate()));
//        match.append("shipdate",dateRange);
//        BasicDBObject cond = new BasicDBObject();
//        BasicDBObject project = new BasicDBObject();
//        Object[] str = new Object[2];
//        Object[] str2 = new Object[2];
//        str2[0] = 1;
//        str2[1] = "$discount";
//        str[0] = "$extendedprice";
//        str[1] = new BasicDBObject("$subtract", str2);
//        project.append("_id", 0)
//                .append("revenue", new BasicDBObject("$multiply", str))
//                .append("supplier_no", "$partsupp.supplier.suppkey")
//                .append("name", "$partsupp.supplier.name")
//                .append("address", "$partsupp.supplier.address")
//                .append("phone", "$partsupp.supplier.phone");
//
//        BasicDBObject group = new BasicDBObject();
//        group.append("_id", "$supplier_no")
//                .append("total_revenue", new BasicDBObject("$sum", "$revenue"))
//                .append("name", new BasicDBObject("$first", "$name"))
//                .append("address", new BasicDBObject("$first", "$address"))
//                .append("phone", new BasicDBObject("$first", "$phone"));
//
//        DBCollection tmp = db.getCollection("tmp");
//        tmp.drop();
//        AggregationOutput output = collection.aggregate(
//                new BasicDBObject("$match", match), new BasicDBObject("$project", project), new BasicDBObject("$group", group));
//        Iterable<DBObject> list = output.results();
//        for(DBObject dbObject:list){
//            tmp.insert(dbObject);
//        }
//        System.out.println(tmp.findOne().toString());
//        DBCursor cursor = tmp.find().sort(new BasicDBObject("total_revenue", -1)).limit(1);
//        /*while(cursor.hasNext()){
//            DBObject obj = cursor.next();
//            System.out.println(obj.toString());
//        }*/
//
//        return null;
//    }

    private static class TestQ15{
        public static void main(String[] args){
            Configuration config = new Configuration();
            config.setBenchmark("tpch");
            config.setDb_username("root");
            config.setDb_password("123456");
            Q15Mongo q15Mongo = new Q15Mongo();
            DBConnection dbConnection =new ConnectionMongo(config);
            q15Mongo.run(dbConnection);
        }
    }
}